//+------------------------------------------------------------------+
//|                                                           ma.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

extern int longMa = 20;
extern int shortMa = 10;
extern int callbackMa = 30;

extern int stop = 300;
extern int limit =900;
extern double lots = 0.01;
extern double trailingStop = 500;
extern int magic = 12345;
extern int goodK = 2;

//是否交叉
bool isCrossBuy = false;
bool isCrossSell = false;

//是否回调到支撑线
bool isBuyCallback = false;
bool isSellCallback = false;

//是否开仓
bool isBuyOpend =false;
bool isSellOpend = false;

datetime buytime = 0;
datetime selltime =0;

// 定义交易时间段的开始和结束时间
input int startTime = 14;  // 交易开始时间
input int endTime = 21;    // 交易结束时间


input int BollPeriod = 20;             // 布林带周期
input double BollDeviation = 2.0;      // 布林带标准差倍数
input int MACDFastPeriod = 12;         // MACD 快线周期
input int MACDSlowPeriod = 26;         // MACD 慢线周期
input int MACDSignalPeriod = 9;        // MACD 信号线周期


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+


// 设置固定时间
bool IsInTradingHours()
  {
   datetime current_time = TimeCurrent(); // 获取当前时间
   int hour = TimeHour(current_time); // 获取当前小时
   Print(hour);
   if(hour >= startTime && hour < endTime)    // 检查是否在9:00到15:00之间
     {
      return true;
     }
   else
     {
      return false;
     }
  };


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(!IsInTradingHours())
     {
      Print("当前时间不在交易时间内");
      closesell(Symbol()+"sell",magic);
      closebuy(Symbol()+"buy",magic);
      return;
     };

   double totalProfit = CalculateTotalProfit();
   Print("总收入: ", totalProfit);


    // 获取当前价格
    double currentPrice = Close[0];

    // 计算 MA 值
    double maValue = iMA(NULL, 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);

    // 计算布林带值
    double upperBand = iBands(NULL, 0, BollPeriod, BollDeviation, 0, PRICE_CLOSE, MODE_UPPER, 0);
    double lowerBand = iBands(NULL, 0, BollPeriod, BollDeviation, 0, PRICE_CLOSE, MODE_LOWER, 0);

    // 计算 MACD 值
    double macdValue = iMACD(NULL, 0, MACDFastPeriod, MACDSlowPeriod, MACDSignalPeriod, PRICE_CLOSE, MODE_MAIN, 0);
    double signalValue = iMACD(NULL, 0, MACDFastPeriod, MACDSlowPeriod, MACDSignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 0);

//   lots = MathFloor((AccountBalance()/10000));
//获取所有均线价格，包括长期，短期，回调
   double longmaprice1 = iMA(NULL,0,longMa,0,MODE_SMA,PRICE_CLOSE,1);
   double longmaprice2 = iMA(NULL,0,longMa,0,MODE_SMA,PRICE_CLOSE,2);
   double shortmaprice1 = iMA(NULL,0,shortMa,0,MODE_SMA,PRICE_CLOSE,1);
   double shortmaprice2 = iMA(NULL,0,shortMa,0,MODE_SMA,PRICE_CLOSE,2);
   double callbackprice = iMA(NULL,0,callbackMa,0,MODE_SMA,PRICE_CLOSE,0);

// 均线交叉多头
   if(shortmaprice1>longmaprice1 && shortmaprice2<longmaprice2)
     {
      isCrossBuy = true;
      isCrossSell = false;
      isSellOpend = false;
      isSellCallback = false;
      closesell(Symbol()+"sell",magic);
     }

// 均线交叉空头
   if(shortmaprice1<longmaprice1 && shortmaprice2>longmaprice2)
     {
      isCrossBuy = false;
      isCrossSell = true;
      isBuyOpend = false;
      isBuyCallback = false;
      closebuy(Symbol()+"buy",magic);
     }

   double lowPrice = Low[0];
   double highPrice = High[0];
   double openPrice = Open[0];
   double closePrice = Close[0];

   double lowPrice1 = Low[1];
   double highPrice1 = High[1];
   double openPrice1 = Open[1];
   double closePrice1 = Close[1];

//下影线是上影线的2倍，然后实体是下影线的2倍
   bool isGoodbuyK = goodK*(highPrice1 - closePrice1)<openPrice1-lowPrice1 && (closePrice1-openPrice1)>goodK*(openPrice1-lowPrice1);
   if(!isBuyOpend && isCrossBuy && lowPrice < callbackprice &&isGoodbuyK && currentPrice >= upperBand && macdValue > signalValue)
     {
      //符合下多的条件
      //第一个问题：一直下单
      //第二个问题：一次交叉里面，只希望做一单
      //解决当前这根K线，重复下单的问题
      if(buytime!=Time[0])
        {
         if(buy(lots,stop,limit,Symbol()+"buy",magic))
           {
            buytime = Time[0];
            isBuyOpend = true;
           }

        }
     }

   bool isGoodSellK = (highPrice1 - openPrice1)>goodK*(closePrice1-lowPrice1) && (openPrice1-closePrice1) > goodK*(highPrice1-openPrice1);
   if(!isSellOpend && isCrossSell && highPrice>callbackprice && isGoodSellK && currentPrice <= lowerBand && macdValue < signalValue)
     {
      if(selltime!=Time[0])
        {
         if(sell(lots,stop,limit,Symbol()+"sell",magic))
           {
            selltime = Time[0];
            isSellOpend = true;
           }

        }
     }

   yidongzhisun();
  }


//
double CalculateTotalProfit()
  {
   double totalProfit = 0;
   for(int i = OrdersHistoryTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
         totalProfit += OrderProfit();
         // 获取订单信息
         int ticket = OrderTicket();          // 订单号
         double profit = OrderProfit();       // 订单收益
         double openPrice = OrderOpenPrice(); // 开仓价格
         double stopLoss = OrderStopLoss();   // 止损价格
         double takeProfit = OrderTakeProfit(); // 止盈价格
         int orderType = OrderType();        // 订单类型

         Print(orderType);
         Print("当前订单收益:",profit);
         if(profit>7 && orderType == OP_BUY)
           {
            closebuy(Symbol()+"buy",magic);
            return;
           };

         if(profit>7 && orderType == OP_SELL)
           {
            closesell(Symbol()+"sell",magic);
            return;
           };


         if(profit>6 && orderType == OP_BUY)
           {
            closebuy(Symbol()+"buy",magic);
            return;
           };

         if(profit>6 && orderType == OP_SELL)
           {
            closesell(Symbol()+"sell",magic);
            return;
           };

         if(profit>5 && orderType == OP_BUY)
           {
            closebuy(Symbol()+"buy",magic);
            return;
           };

         if(profit>5 && orderType == OP_SELL)
           {
            closesell(Symbol()+"sell",magic);
            return;
           };



         if(profit>3 && orderType == OP_BUY)
           {
            closebuy(Symbol()+"buy",magic);
            return;
           };

         if(profit>3 && orderType == OP_SELL)
           {
            closesell(Symbol()+"sell",magic);
            return;
           };

         Print("订单总收益:",totalProfit);
        }
     }
   return totalProfit;
  }


//下单函数，针对一个单子的
int buy(double lots,double sl,double tp,string comm,int buymagic)
  {
   int returnTicket = 0;
   bool zhaodan = false;
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         string zhushi = OrderComment();
         int magicNumber = OrderMagicNumber();
         if(OrderSymbol()==Symbol() && OrderType() == OP_BUY && zhushi==comm && magicNumber==buymagic)
           {
            zhaodan=true;
            break;
           }
        }
     }

   if(zhaodan==false)
     {
      if(sl!=0 && tp==0)
        {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,Ask-sl*Point,0,comm,buymagic,0,White);
        }
      if(sl==0 && tp!=0)
        {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,0,Ask+tp*Point,comm,buymagic,0,White);
        }
      if(sl==0 && tp==0)
        {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,0,0,comm,buymagic,0,White);
        }
      if(sl!=0 && tp!=0)
        {
         returnTicket = OrderSend(Symbol(),OP_BUY,lots,Ask,50,Ask-sl*Point,Ask+tp*Point,comm,buymagic,0,White);
        }
     }
   return(returnTicket);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int sell(double lots,double sl,double tp,string comm,int sellmagic)
  {
   int returnTicket = 0;
   bool zhaodan = false;
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         string zhushi = OrderComment();
         int magicNumber = OrderMagicNumber();
         if(OrderSymbol()==Symbol() && OrderType() == OP_SELL && zhushi==comm && magicNumber==sellmagic)
           {
            zhaodan=true;
            break;
           }
        }
     }

   if(zhaodan==false)
     {
      if(sl!=0 && tp==0)
        {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,Bid+sl*Point,0,comm,sellmagic,0,White);
        }
      if(sl==0 && tp!=0)
        {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,0,Bid-tp*Point,comm,sellmagic,0,White);
        }
      if(sl==0 && tp==0)
        {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,0,0,comm,sellmagic,0,White);
        }
      if(sl!=0 && tp!=0)
        {
         returnTicket = OrderSend(Symbol(),OP_SELL,lots,Bid,50,Bid+sl*Point,Bid-tp*Point,comm,sellmagic,0,White);
        }
     }
   return(returnTicket);
  }

//平一个货币，同一个方向的单子，因为本系统一个货币，一个方向，只会有一个单子存在
void closebuy(string comm,int magic)
  {
   int t = OrdersTotal();
   for(int i=t-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY && OrderComment()==comm && OrderMagicNumber() == magic)
           {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),300,Green);
           }
        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void closesell(string comm,int magic)
  {
   int t = OrdersTotal();
   for(int i=t-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL && OrderComment()==comm && OrderMagicNumber() == magic)
           {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),300,Green);
           }
        }
     }
  }

//设置移动止损
void yidongzhisun()
  {
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true)
        {
         if(OrderType()==OP_BUY && OrderSymbol()==Symbol() && OrderMagicNumber()==magic)
           {
            if((Bid-OrderOpenPrice())>=Point*trailingStop)
              {
               if(OrderStopLoss()<(Bid-Point*trailingStop) || (OrderStopLoss()==0))
                 {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*trailingStop,OrderTakeProfit(),0,Green);
                 }
              }
           }

         if(OrderType()==OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber()==magic)
           {
            if((OrderOpenPrice()-Ask)>=Point*trailingStop)
              {
               if(OrderStopLoss()>(Ask+Point*trailingStop) || (OrderStopLoss()==0))
                 {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*trailingStop,OrderTakeProfit(),0,Green);
                 }
              }
           }
        }
     }
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
